 /***************************************************************************
 * Copyright (C) 2012
 * by Dj_Skual
 *
 * This software is provided 'as-is', without any express or implied
 * warranty. In no event will the authors be held liable for any
 * damages arising from the use of this software.
 *
 * Permission is granted to anyone to use this software for any
 * purpose, including commercial applications, and to alter it and
 * redistribute it freely, subject to the following restrictions:
 *
 * 1. The origin of this software must not be misrepresented; you
 * must not claim that you wrote the original software. If you use
 * this software in a product, an acknowledgment in the product
 * documentation would be appreciated but is not required.
 *
 * 2. Altered source versions must be plainly marked as such, and
 * must not be misrepresented as being the original software.
 *
 * 3. This notice may not be removed or altered from any source
 * distribution.
 *
 * DeviceMenu.cpp
 *
 * for SaveGame Manager GX 2012
 ***************************************************************************/
#include "DeviceMenu.h"
#include "../Themes/CTheme.h"
#include "../Menu/TaskBar.hpp"
#include "../Controls/Application.h"

#define	MAX_DEVICES_BUTTONS	4

DeviceMenu::DeviceMenu()
	:GuiFrame(0, 0)
{
	imgSelect.clear();
	imgDevice.clear();
	txtDevice.clear();
	deviceBtn.clear();
	deviceSelection.clear();
	
	btnSoundClick = Resources::GetSound("button_click.wav");
	btnSoundOver = Resources::GetSound("button_over.wav");
	btnSoundClick->SetVolume(Settings.SFXVolume);
	btnSoundOver->SetVolume(Settings.SFXVolume);
	
	trigA.SetSimpleTrigger(-1, WiiControls.ClickButton | ClassicControls.ClickButton << 16, GCControls.ClickButton);
	trigB.SetButtonOnlyTrigger(-1, WiiControls.BackButton | ClassicControls.BackButton << 16, GCControls.BackButton);
	trigLeft.SetButtonOnlyTrigger(-1, WiiControls.LeftButton | ClassicControls.LeftButton << 16, GCControls.LeftButton);
	trigRight.SetButtonOnlyTrigger(-1, WiiControls.RightButton | ClassicControls.RightButton << 16, GCControls.RightButton);
	trigMinus.SetButtonOnlyTrigger(-1, WiiControls.PrevButton | ClassicControls.PrevButton << 16, 0);
	trigPlus.SetButtonOnlyTrigger(-1, WiiControls.NextButton | ClassicControls.NextButton << 16, 0);

	dataLeft = Resources::GetImageData("device_choose_left.png");
	dataCenter = Resources::GetImageData("device_choose_center.png");
	dataRight = Resources::GetImageData("device_choose_right.png");
	
	imgLeft = new GuiImage(dataLeft);
	imgCenter = new GuiImage(dataCenter);
	imgRight = new GuiImage(dataRight);
	
	dataArrowLeft = Resources::GetImageData("arrow_left.png");
	dataArrowRight = Resources::GetImageData("arrow_right.png");
	
	imgArrowLeft = new GuiImage(dataArrowLeft);
	imgArrowRight = new GuiImage(dataArrowRight);
	imgArrowLeft->SetScale(0.5);
	imgArrowRight->SetScale(0.5);
	imgArrowLeft->SetAlignment(ALIGN_CENTER | ALIGN_MIDDLE);
	imgArrowRight->SetAlignment(ALIGN_CENTER | ALIGN_MIDDLE);
	
	dataSelect = Resources::GetImageData("device_selection.png");

	dataSD = Resources::GetImageData("device_choose_sd.png");
	dataUSB = Resources::GetImageData("device_choose_usb.png");
	dataWII = Resources::GetImageData("device_choose_wii.png");
	dataEWII = Resources::GetImageData("device_choose_emu.png");
	dataMII = Resources::GetImageData("device_choose_mii.png");
	dataEMII = Resources::GetImageData("device_choose_emu_mii.png");
	dataGC = Resources::GetImageData("device_choose_gc.png");
	
	FontSize = thInt("17 - device menu text size");
	firstDevice = 0;
	deviceCount = 0;
	
	if(DeviceHandler::Instance()->IsInserted(SD))
	{
		AddButton(dataSD, SD);
		deviceCount++;
	}
	
	for(int usb = USB1; usb <= USB9; ++usb)
	{
		if(DeviceHandler::Instance()->IsInserted(usb))
		{
			AddButton(dataUSB, usb);
			deviceCount++;
		}
	}
	
	if(DeviceHandler::Instance()->IsInserted(NAND))
	{
		AddButton(dataWII, WII);
		deviceCount++;
		
		AddButton(dataMII, MII);
		deviceCount++;
	}
	
	for(int ewii = EWII1; ewii <= EWII3; ++ewii)
	{
		if(DeviceHandler::Instance()->IsInserted(ewii))
		{
			AddButton(dataEWII, ewii);
			deviceCount++;
		}
		
		if(DeviceHandler::Instance()->IsInserted(ewii+3))
		{
			AddButton(dataEMII, ewii+3);
			deviceCount++;
		}
	}
	
	if(DeviceHandler::Instance()->IsInserted(GCA))
	{
		AddButton(dataGC, GCA);
		deviceCount++;
	}
	
	if(DeviceHandler::Instance()->IsInserted(GCB))
	{
		AddButton(dataGC, GCB);
		deviceCount++;
	}
	
	int x = TaskBar::Instance()->GetLeft() - 5;
	int y = TaskBar::Instance()->GetTop() + TaskBar::Instance()->GetHeight();
	
	SetPosition(x, y);
	
	//!found max button width
	mawBtnWidth = 0;
	for(int i = 0; i < deviceCount; i++)
	{
		if(imgDevice[i]->GetWidth() > mawBtnWidth)
			mawBtnWidth = imgDevice[i]->GetWidth();
		if(txtDevice[i]->GetTextWidth() > mawBtnWidth)
			mawBtnWidth = txtDevice[i]->GetTextWidth();
	}
	
	btnSpace = 5;
	int leftLimit = this->GetLeft() + imgLeft->GetWidth() - imgCenter->GetWidth();
	int rigthLimit = leftLimit + (MIN(deviceCount, MAX_DEVICES_BUTTONS) * mawBtnWidth) + ((MIN(deviceCount, MAX_DEVICES_BUTTONS)-1) * btnSpace);
	
	//!Set each button
	for(int i = 0; i < deviceCount; i++)
	{
		deviceBtn[i]->SetSize(mawBtnWidth, imgDevice[i]->GetHeight()+FontSize);
		deviceBtn[i]->SetPosition(i*(mawBtnWidth+btnSpace)+imgLeft->GetWidth()-imgCenter->GetWidth(), 19);
		deviceBtn[i]->SetLabel(txtDevice[i]);
		deviceBtn[i]->SetImageOver(imgSelect[i]);
		deviceBtn[i]->SetIcon(imgDevice[i]);
		deviceBtn[i]->SetSoundClick(btnSoundClick);
		deviceBtn[i]->SetSoundOver(btnSoundOver);
		deviceBtn[i]->SetTrigger(&trigA);
		deviceBtn[i]->SetBounds(iRect(leftLimit, 0, rigthLimit, screenheight));
		deviceBtn[i]->Clicked.connect(this, &DeviceMenu::OnButtonClick);
		deviceBtn[i]->SetState(STATE_DISABLED);
	}
	
	for(int i = firstDevice; (i < MAX_DEVICES_BUTTONS) && (i < deviceCount); i++)
		deviceBtn[i]->SetState(STATE_DEFAULT);
	
	//! Set background images position and tile
	int tile = (rigthLimit-leftLimit)/imgCenter->GetWidth()-1;
	width = imgLeft->GetWidth() + tile * imgCenter->GetWidth() + imgRight->GetWidth();
	height = imgLeft->GetHeight();
	
	imgCenter->SetPosition(imgLeft->GetWidth(), 0);
	imgCenter->SetTileHorizontal(tile);
	
	imgRight->SetAlignment(ALIGN_LEFT | ALIGN_TOP);
	imgRight->SetPosition(imgLeft->GetWidth() + tile * imgCenter->GetWidth(), 0);
	
	noBtn = new GuiButton(screenwidth, screenheight);
	noBtn->SetPosition(-x, -y);
	noBtn->SetTrigger(&trigA);
	noBtn->SetRumble(false);
	noBtn->Clicked.connect(this, &DeviceMenu::OnCloseButtonClick);
	
	closeBtn = new GuiButton(0, 0);
	closeBtn->SetTrigger(&trigB);
	closeBtn->Clicked.connect(this, &DeviceMenu::OnCloseButtonClick);
	
	leftBtn = new GuiButton(imgArrowLeft->GetWidth()/2, imgArrowLeft->GetHeight()/2);
	leftBtn->SetAlignment(ALIGN_LEFT | ALIGN_MIDDLE);
	leftBtn->SetPosition(imgLeft->GetWidth()/2-imgArrowLeft->GetWidth()/4, 0);
	leftBtn->SetImage(imgArrowLeft);
	leftBtn->SetSoundClick(btnSoundClick);
	leftBtn->SetSoundOver(btnSoundOver);
	leftBtn->SetTrigger(&trigA);
	leftBtn->SetTrigger(&trigLeft);
	leftBtn->SetTrigger(&trigMinus);
	leftBtn->SetEffectGrow();
	leftBtn->Clicked.connect(this, &DeviceMenu::OnArrowButtonClick);
	
	rightBtn = new GuiButton(imgArrowRight->GetWidth()/2, imgArrowRight->GetHeight()/2);
	rightBtn->SetAlignment(ALIGN_RIGHT | ALIGN_MIDDLE);
	rightBtn->SetPosition(-imgRight->GetWidth()/2+imgArrowRight->GetWidth()/4, 0);
	rightBtn->SetImage(imgArrowRight);
	rightBtn->SetSoundClick(btnSoundClick);
	rightBtn->SetSoundOver(btnSoundOver);
	rightBtn->SetTrigger(&trigA);
	rightBtn->SetTrigger(&trigRight);
	rightBtn->SetTrigger(&trigPlus);
	rightBtn->SetEffectGrow();
	rightBtn->Clicked.connect(this, &DeviceMenu::OnArrowButtonClick);
	
	Append(noBtn);
	Append(closeBtn);
	Append(imgLeft);
	Append(imgCenter);
	Append(imgRight);
	for(int i = 0; i < deviceCount; i++)
		Append(deviceBtn[i]);
	if(deviceCount > MAX_DEVICES_BUTTONS)
	{
		Append(leftBtn);
		Append(rightBtn);
	}
	
	SetEffect(EFFECT_FADE, 20);
	
	Application::Instance()->SetUpdateOnly(this);
	Application::Instance()->Append(this);
}

DeviceMenu::~DeviceMenu()
{
	RemoveAll();
	
	deviceSelection.clear();
	
	Resources::Remove(dataLeft);
	Resources::Remove(dataCenter);
	Resources::Remove(dataRight);
	Resources::Remove(dataArrowLeft);
	Resources::Remove(dataArrowRight);
	Resources::Remove(dataSelect);
	Resources::Remove(dataSD);
	Resources::Remove(dataUSB);
	Resources::Remove(dataWII);
	Resources::Remove(dataEWII);
	Resources::Remove(dataMII);
	Resources::Remove(dataEMII);
	Resources::Remove(dataGC);
	
	delete imgLeft;
	delete imgCenter;
	delete imgRight;
	
	delete imgArrowLeft;
	delete imgArrowRight;
	
	for(int i = 0; i < (int)deviceSelection.size(); ++i)
	{
		delete imgSelect[i];
		delete imgDevice[i];
		delete txtDevice[i];
		delete deviceBtn[i];
	}
	imgSelect.clear();
	imgDevice.clear();
	txtDevice.clear();
	deviceBtn.clear();
	
	delete noBtn;
	delete closeBtn;
	delete leftBtn;
	delete rightBtn;
	
	Resources::Remove(btnSoundClick);
	Resources::Remove(btnSoundOver);
}

void DeviceMenu::AddButton(GuiImageData * imgData, int dev)
{
	int size = deviceBtn.size();
	
	imgSelect.push_back(new GuiImage(dataSelect));
	imgSelect[size]->SetAlignment(ALIGN_CENTER | ALIGN_MIDDLE);
	
	imgDevice.push_back(new GuiImage(imgData));
	imgDevice[size]->SetAlignment(ALIGN_CENTER | ALIGN_TOP);
	
	txtDevice.push_back(new GuiText(DeviceName[dev], FontSize, thColor("r=0 g=0 b=0 a=255 - device menu text color")));
	txtDevice[size]->SetAlignment(ALIGN_CENTER | ALIGN_BOTTOM);
	txtDevice[size]->SetPosition(0, 2);
	
	deviceBtn.push_back(new GuiButton(0, 0));
	
	deviceSelection.push_back(dev);
}

void DeviceMenu::OnButtonClick(GuiButton *sender, int pointer UNUSED, const POINT &p UNUSED)
{
	Application::Instance()->ResetPads();
	
	for(int i = 0; i < (int)deviceSelection.size(); ++i)
	{
		if(sender != deviceBtn[i])
			continue;
		
		Clicked(this, deviceSelection[i]);
		break;
	}
}

void DeviceMenu::OnCloseButtonClick(GuiButton *sender, int pointer UNUSED, const POINT &p)
{
	if((sender == noBtn && !IsInside(p.x, p.y)) || sender == closeBtn)
		Clicked(this, -1);
}

void DeviceMenu::OnArrowButtonClick(GuiButton *sender, int pointer UNUSED, const POINT &p UNUSED)
{
	Application::Instance()->ResetPads();
	
	if(sender == leftBtn)
	{
		if(firstDevice == 0)
			return;
		
		firstDevice--;
		
		for(int i = 0; i < (int)deviceBtn.size(); ++i)
		{
			deviceBtn[i]->SetEffect(EFFECT_MOVE | EFFECT_MOVE_HOR, 5, deviceBtn[i]->GetLeft() - this->GetLeft() + (mawBtnWidth + btnSpace));
			deviceBtn[i]->SetState(STATE_DISABLED);
		}
	}
	else
	{
		if(firstDevice == deviceCount-MAX_DEVICES_BUTTONS)
			return;
		
		firstDevice++;
		
		for(int i = 0; i < (int)deviceBtn.size(); ++i)
		{
			deviceBtn[i]->SetEffect(EFFECT_MOVE | EFFECT_MOVE_HOR, 5, deviceBtn[i]->GetLeft() - this->GetLeft() - (mawBtnWidth + btnSpace));
			deviceBtn[i]->SetState(STATE_DISABLED);
		}
	}
	
	while(deviceBtn[0]->IsAnimated())
		Application::Instance()->updateEvents();
	
	for(int i = firstDevice; (i < MAX_DEVICES_BUTTONS+firstDevice) && (i < (int)deviceBtn.size()); i++)
		deviceBtn[i]->SetState(STATE_DEFAULT);
}
